/******************************************************************
 * Copyright (c) 2007 - 2007, Simon Guerard, All rights reserved.
 * 
 * Projet de jeu de course au large.
 * 
 * This File is part of Sail-Race
 * 
 * Sail-Race is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * Sail-Race is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * Sail-Race; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
 * Fifth Floor, Boston, MA 02110-1301 USA
 */

package net.simcafamily.sailrace.core;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.annotation.Resource;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.plaf.metal.MetalLookAndFeel;

import net.simcafamily.sailrace.listener.QuitListener;
import net.simcafamily.sailrace.panel.SimpleInternalFrame;
import net.simcafamily.sailrace.spring.ContextFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hsqldb.server.Server;
import org.xnap.commons.i18n.I18n;
import org.xnap.commons.i18n.I18nFactory;

import com.jgoodies.looks.Options;
import com.jgoodies.looks.plastic.PlasticLookAndFeel;
import com.jgoodies.looks.plastic.PlasticXPLookAndFeel;
import com.jgoodies.looks.plastic.theme.DesertBluer;

/**
 * @version $Revision$
 * @author $Author$
 */
@org.springframework.stereotype.Component("baseVue")
public class BaseVueJFrame extends JFrame implements IView, Runnable {

    /**
     * serialVersionUID.
     */
    private static final long serialVersionUID = -5755919593570170251L;

    /**
     * Termine l'application apres demande de confirmation.
     */
    public static boolean quit(final BaseVueJFrame instance) {
	final int confirm = JOptionPane.showConfirmDialog(instance, instance
		.getI18n().tr("Do you want to quit Sail-Race ?"), "Sail-Race",
		JOptionPane.YES_NO_OPTION);

	if (confirm == JOptionPane.YES_OPTION) {
	    for (final QuitListener quitListener : instance.getQuitListeners()) {
		quitListener.quit();
	    }
	    instance.getQuitListeners().clear();

	    instance.dispose();
	    System.exit(0);
	    return true;
	}

	return false;
    }

    // nom de la vue
    private String nom;

    // nom de l'action que le controleur doit executer
    private String action;

    private final ArrayList<QuitListener> quitListeners;

    private SimpleInternalFrame managerFrame;

    // session de l'application commune aux vues et actions
    @Resource(name = "session")
    private Session session;

    @Resource(name = "synchro")
    private Synchronisateur synchro;

    protected final I18n i18n = I18nFactory.getI18n(getClass());

    private static final Log LOGGER = LogFactory.getLog(BaseVueJFrame.class);

    /**
     * @throws HeadlessException
     */
    public BaseVueJFrame() {
	quitListeners = new ArrayList<QuitListener>();

	// ajout d'un listerner pour l'arret propre de la base de donnees HSQL
	quitListeners.add(new QuitListener() {

	    @Override
	    public void quit() {
		Server server = (Server) ContextFactory.getContext().getBean(
			"hsqlServer");
		server.stop();
	    }
	});
    }

    /**
     * Ajoute un ecouteur de fin de session.
     * 
     * @param listener
     *            Ecouteur a notifier de la fin de session
     */
    public void addQuitListener(final QuitListener listener) {
	quitListeners.add(listener);
    }

    /**
     * Construit le panneau de composants principal. Au retour de cette methode,
     * tous les composants graphiques de la fenetre ont ete crees.
     * 
     * @return Le panneau de composants principal. Il s'agit du pere de tous les
     *         composants de l'application.
     */
    @Override
    public Container buildContentPane() {
	managerFrame = new SimpleInternalFrame();
	// contenu par defaut, intro animee
	managerFrame.setContent(new JPanel());

	// panneau de la fenetre
	final JPanel pane = new JPanel(new BorderLayout());
	pane.add(BorderLayout.CENTER, managerFrame);
	return pane;
    }

    /**
     * Applique les parametres de l'IHM en fonction des donnees du membre
     * settings. Ce code est extrait de la demo Looks de jgoodies.com, voir
     * en-tete du fichier. *
     * 
     * @author Karsten Lentzsch
     * @author Romain Guy
     */
    private void configureUI() {
	Options.setDefaultIconSize(new Dimension(18, 18));

	UIManager.put(Options.USE_SYSTEM_FONTS_APP_KEY, true);
	Options.setUseNarrowButtons(false);

	Options.setTabIconsEnabled(true);
	UIManager.put(Options.POPUP_DROP_SHADOW_ENABLED_KEY, true);

	final LookAndFeel selectedLaf = new PlasticXPLookAndFeel();
	MetalLookAndFeel.setCurrentTheme(new DesertBluer());
	PlasticLookAndFeel
		.setTabStyle(PlasticLookAndFeel.TAB_STYLE_DEFAULT_VALUE);
	PlasticLookAndFeel.setHighContrastFocusColorsEnabled(false);

	final JRadioButton radio = new JRadioButton();
	radio.getUI().uninstallUI(radio);
	final JCheckBox checkBox = new JCheckBox();
	checkBox.getUI().uninstallUI(checkBox);

	try {
	    UIManager.setLookAndFeel(selectedLaf);
	} catch (final Exception e) {
	    BaseVueJFrame.LOGGER.error("Can't change L&F: " + e);
	}

	setSize(900, 600);
	// setUndecorated(true);
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * @return Returns the action.
     */
    @Override
    public String getActionName() {
	return action;
    }

    /**
     * @return the i18n
     */
    public I18n getI18n() {
	return i18n;
    }

    /**
     * @return the managerFrame
     */
    public final SimpleInternalFrame getManagerFrame() {
	return managerFrame;
    }

    /**
     * @return Returns the nom.
     */
    @Override
    public String getNom() {
	return nom;
    }

    /**
     * @return the quitListeners
     */
    public ArrayList<QuitListener> getQuitListeners() {
	return quitListeners;
    }

    // getters-setters
    public Session getSession() {
	return session;
    }

    /**
     * @return the synchro
     */
    public final Synchronisateur getSynchro() {
	return synchro;
    }

    public void init() throws HeadlessException {
	configureUI();
	// on ajoute le menu a la fenetre
	enableEvents(AWTEvent.WINDOW_EVENT_MASK);

	// configureUI();
	setContentPane(buildContentPane());
	// setTitle("Sail-Race");

	setSize(new java.awt.Dimension(900, 600));
	setResizable(false);
	UIHelper.centerOnScreen(this);

	setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
	addWindowListener(new WindowAdapter() {

	    @Override
	    public void windowClosing(final WindowEvent evt) {
		BaseVueJFrame.quit((BaseVueJFrame) ContextFactory.getContext()
			.getBean("baseVue"));
	    }
	});
    }

    /**
     * @see net.simcafamily.sailrace.core.IForward#isVueInstance()
     */
    @Override
    public boolean isVueInstance() {
	return true;
    }

    /**
     * Retire l'ecouteur.
     * 
     * @param listener
     *            L'ecouteur a retirer
     */
    public void removeQuitListener(final QuitListener listener) {
	quitListeners.remove(listener);
    }

    // methode du thread d'affichage
    @Override
    public void run() {
	// affichage de la vue
	setVisible(true);
    }

    /**
     * @param action
     *            The action to set.
     */
    public void setActionName(final String action) {
	this.action = action;
    }

    /**
     * @param nom
     *            The nom to set.
     */
    @Override
    public void setNom(final String nom) {
	this.nom = nom;
    }

    public void setSession(final Session session) {
	this.session = session;
    }

    /**
     * @param pSynchro
     *            the synchro to set
     */
    public final void setSynchro(final Synchronisateur pSynchro) {
	synchro = pSynchro;
    }

}
